﻿#include "StdAfx.h"
#include "NMOcciDB.h"

#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif

/*
NMOcciDB::NMOcciDB(void)
{
}

NMOcciDB::~NMOcciDB(void)
{
}
*/

bool NMOcciDB::OnLogin(Peer& peer, packLogon& logon, packFBLogon& fblogon, bool& isloged)
{
	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			sql = "SELECT t.USERID, t.USERMAIL, t.USERTYPE, t.NICKNAME, t.GENDER, t.BIRTHDAY, "
				"t.NATIVEPLACE, t.LOCALITY, t.VOCATION, t.COMPANY, t.REMARK, t.BALANCE, t.MATURITY, "
				"t.REGISTERDATE, t.LASTLOGIN, t.ISLOGIN "
				" FROM DBF_USER_INFO t WHERE ( USERID = \'" + 
				boost::lexical_cast<string>(atol((const char *)logon.username)) + "\'"
				" OR USERMAIL = \'" + boost::lexical_cast<string>(logon.username) + "\'"
				" ) AND PASSWORD = \'" + boost::lexical_cast<string>(logon.password) + "\'";

			memset(&fblogon, 0, sizePackFBLogon);
			fblogon.type = MSG_PACK_FBLOGON;
			fblogon.packsize = sizePackFBLogon;
			fblogon.flag = INFO_ERROR_UNKOWN;

			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());
			if (!stmt.IsValid())
				break;

 			COcciResultSet rs(stmt);
 			if (!rs.IsValid())
 				break;

 			if (!rs->next())
 				break;
 
			string strVal;
			int nVal;
			double dbVal;
			Date dateVal;
			DATETIME time;

			// 用户ID.
			strVal = rs->getString(1);
 			strncpy((char *)fblogon.userid, strVal.c_str(), strVal.length());
			
			// 用户email.
			strVal = rs->getString(2);
			strncpy((char *)fblogon.usermail, strVal.c_str(), strVal.length());

			// 用户类型.
			nVal = rs->getInt(3);
			fblogon.usertype = nVal;

			// 用户昵称.
			strVal = rs->getString(4);
			strncpy((char *)fblogon.nickname, strVal.c_str(), strVal.length());

			// 用户性别.
			strVal = rs->getString(5);
			strncpy((char *)fblogon.gender, strVal.c_str(), strVal.length());
			
			// 用户出生日期.
			dateVal = rs->getDate(6);
			if (!dateVal.isNull())
			{
				dateVal.getDate(time.iYear, time.uiMonth, time.uiDay, time.uiHour, time.uiMinute, time.uiSecond);
				strVal = boost::str(boost::format("%1$04d-%2$02d-%3$02d")%time.iYear%time.uiMonth%time.uiDay);
				strncpy((char *)fblogon.birthday, strVal.c_str(), 11);
			}			

			// 用户籍贯.
			strVal = rs->getString(7);
			strncpy((char *)fblogon.nativeplace, strVal.c_str(), strVal.length());

			// 用户所在地.
			strVal = rs->getString(8);
			strncpy((char *)fblogon.locality, strVal.c_str(), strVal.length());

			// 用户所在行业.
			strVal = rs->getString(9);
			strncpy((char *)fblogon.vocation, strVal.c_str(), strVal.length());

			// 用户所在公司.
			strVal = rs->getString(10);
			strncpy((char *)fblogon.company, strVal.c_str(), strVal.length());

			// 用户备注.
			strVal = rs->getString(11);
			strncpy((char *)fblogon.remark, strVal.c_str(), strVal.length());

			// 用户余额.
			dbVal = rs->getFloat(12);
			fblogon.balance = dbVal;

			// 用户账户到期时间.
			dateVal = rs->getDate(13);
			if (!dateVal.isNull())
			{
				dateVal.getDate(time.iYear, time.uiMonth, time.uiDay, time.uiHour, time.uiMinute, time.uiSecond);
				strVal = boost::str(boost::format("%1$04d-%2$02d-%3$02d %4$02d:%5$02d:%6$02d")%time.iYear%time.uiMonth%time.uiDay%time.uiHour%time.uiMinute%time.uiSecond);
				strncpy((char *)fblogon.maturity, strVal.c_str(), 20);
			}

			// 用户注册时间.
			dateVal = rs->getDate(14);
			if (!dateVal.isNull())
			{
				dateVal.getDate(time.iYear, time.uiMonth, time.uiDay, time.uiHour, time.uiMinute, time.uiSecond);
				strVal = boost::str(boost::format("%1$04d-%2$02d-%3$02d %4$02d:%5$02d:%6$02d")%time.iYear%time.uiMonth%time.uiDay%time.uiHour%time.uiMinute%time.uiSecond);
				strncpy((char *)fblogon.registerdate, strVal.c_str(), 20);
			}

			// 用户最后登陆时间.
			dateVal = rs->getDate(15);		
			if (!dateVal.isNull())
			{
				dateVal.getDate(time.iYear, time.uiMonth, time.uiDay, time.uiHour, time.uiMinute, time.uiSecond);
				strVal = boost::str(boost::format("%1$04d-%2$02d-%3$02d %4$02d:%5$02d:%6$02d")%time.iYear%time.uiMonth%time.uiDay%time.uiHour%time.uiMinute%time.uiSecond);
				strncpy((char *)fblogon.lastlogin, strVal.c_str(), 20);
			}

			// 用户是否登陆.
			nVal = rs->getInt(16);
			nVal == 0 ? isloged = false : isloged = true;

			// 设置为登陆状态.
			sql = "UPDATE DBF_USER_INFO SET ISLOGIN = 1 WHERE "
				"( USERID = \'" +	boost::lexical_cast<string>(atol((const char *)logon.username)) + "\' "
				"OR USERMAIL = \'" + boost::lexical_cast<string>(logon.username) + "\' "
				") AND PASSWORD = \'" + boost::lexical_cast<string>(logon.password) + "\' ";

			rs.New(stmt, sql.c_str());
			conn->commit();
		
			rs.Close();

			// 添加登陆事件.
			sql = "INSERT INTO DBF_USER_EVENTS ( "
				"USERID, LOGIN, LOGOUT, NEWSID ) VALUES "
				"(:1, :2, :3, :4)";

			stmt->setSQL(sql);

			stmt->setInt(1, atol((char*)fblogon.userid));
			stmt->setInt(2, 1);
			stmt->setInt(3, 0);
			stmt->setInt(4, 0);

			// 插入记录并提交.
			stmt->executeUpdate();
			conn->commit();

			strncpy((char*)fblogon.information, "登陆成功!", 81);
			fblogon.flag = INFO_SUCCEED;

			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		strncpy((char*)fblogon.information, ex.what(), 81);
		fblogon.flag = INFO_ERROR_EXCEPTION;
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		strncpy((char*)fblogon.information, "ERROR : oracle error !", 81);
		fblogon.flag = INFO_ERROR_EXCEPTION;
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}

bool NMOcciDB::OnLogout(Peer& peer, packLogon& logon)
{
	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			// 设置为未登陆状态.
			sql = "UPDATE DBF_USER_INFO SET ISLOGIN = 0 WHERE "
				"( USERID = \'" +	boost::lexical_cast<string>(atol((const char *)logon.username)) + "\'"
				" OR USERMAIL = \'" + boost::lexical_cast<string>(logon.username) + "\'"
				" ) AND PASSWORD = \'" + boost::lexical_cast<string>(logon.password) + "\'";

			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());

			if (!stmt.IsValid())
				break;

			// 执行sql语句.
			stmt->execute();
			conn->commit();

			// 先得到用户id.
			sql = "SELECT USERID FROM DBF_USER_INFO WHERE "
				"( USERID = \'" +	boost::lexical_cast<string>(atol((const char *)logon.username)) + "\' "
				"OR USERMAIL = \'" + boost::lexical_cast<string>(logon.username) + "\' "
				") AND PASSWORD = \'" + boost::lexical_cast<string>(logon.password) + "\' ";

			stmt->executeQuery(sql);

			COcciResultSet rs(stmt);
			if (!rs.IsValid())
				break;

			if (!rs->next())
				break;

			int userid = rs->getInt(1);

			rs.Close();

			// 添加事件.
			sql = "INSERT INTO DBF_USER_EVENTS ( "
				"USERID, LOGIN, LOGOUT, NEWSID ) VALUES "
				"(:1, :2, :3, :4)";

			stmt->setSQL(sql);

			stmt->setInt(1, userid);
			stmt->setInt(2, 1);
			stmt->setInt(3, 0);
			stmt->setInt(4, 0);

			// 插入记录并提交.
			stmt->executeUpdate();
			conn->commit();

			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}

bool NMOcciDB::OnRegister(Peer& peer, packRegister& registration, packFBRegister& fbregister)
{
	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			// 检查数据库内是否有相同的email.
			sql = "SELECT COUNT(*) AS CNT FROM DBF_USER_INFO WHERE USERMAIL = \'" + 
				boost::lexical_cast<string>(registration.usermail) + "\'";

			memset(&fbregister, 0, sizePackFBRegister);
			fbregister.type = MSG_PACK_FBREGISTER;
			fbregister.packsize = sizePackFBRegister;
			fbregister.flag = INFO_ERROR_UNKOWN;

			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());
			if (!stmt.IsValid())
				break;

			COcciResultSet rs(stmt);
			if (!rs.IsValid())
				break;

			if (!rs->next())
			{
				fbregister.flag = INFO_ERROR_EMPTY;
				strncpy((char*)fbregister.information, "数据库为空!", 81);
				break;
			}

			int nVal;

			// 得到所有记录数.
			nVal = rs->getInt(1);
			if (nVal > 0)	// 邮箱地址已存在.
			{
				fbregister.flag = INFO_ERROR_EXIST;
				strncpy((char*)fbregister.information, "邮箱地址已存在!", 81);
				bRet = false;
				break;
			}

			rs.Close();
			
			string strVal;
			Date dateVal(m_env);
			SYSTEMTIME systimeVal;
			DATETIME dateTimeVal = {0};

			// 插入新记录.
			stmt->setSQL("INSERT INTO DBF_USER_INFO ("
				"USERMAIL, PASSWORD, USERTYPE, NICKNAME, GENDER, "
				"BIRTHDAY, NATIVEPLACE, LOCALITY, VOCATION, COMPANY, "
				"REMARK, REGISTERDATE, ISLOGIN) VALUES "
				"(:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11, :12, :13)");
			
			// 用户邮箱.
			strVal = (char*)registration.usermail;
			stmt->setString(1, strVal);

			// 用户密码.
			strVal = (char*)registration.password;
			stmt->setString(2, strVal);

			// 用户类型.
			stmt->setInt(3, 0);

			// 用户昵称.
			strVal = (char*)registration.nickname;
			stmt->setString(4, strVal);

			// 用户性别.
			strVal = (char*)registration.gender;
			stmt->setString(5, strVal);

			// 用户出生日期.
			strVal = (char*)registration.birthday;
			sscanf((char*)registration.birthday, "%04d-%02d-%02d", 
						&dateTimeVal.iYear, &dateTimeVal.uiMonth, &dateTimeVal.uiDay);
			dateVal.setDate(dateTimeVal.iYear, dateTimeVal.uiMonth, dateTimeVal.uiDay);
			stmt->setDate(6, dateVal);

			// 籍贯.
 			strVal = (char*)registration.nativeplace;
 			stmt->setString(7, strVal);
 
			// 所在地.
 			strVal = (char*)registration.locality;
 			stmt->setString(8, strVal);
 
			// 所在行业.
 			strVal = (char*)registration.vocation;
 			stmt->setString(9, strVal);

			// 公司.
			strVal = (char*)registration.company;
			stmt->setString(10, strVal);

			// 备注信息.
			strVal = (char*)registration.remark;
			stmt->setString(11, strVal);

			// 注册时间.
			GetLocalTime(&systimeVal);
			dateVal.setDate(systimeVal.wYear, systimeVal.wMonth, systimeVal.wDay, 
								systimeVal.wHour, systimeVal.wMinute, systimeVal.wSecond);
			stmt->setDate(12, dateVal);

			// 是否登陆.
			stmt->setInt(13, 0);

			// 执行sql更新.
			stmt->executeUpdate();
			// 提交事务.
			conn->commit();

			// 注册成功.			
			fbregister.flag = INFO_SUCCEED;
			strncpy((char*)fbregister.information, "注册成功!", 81);

			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		fbregister.flag = INFO_ERROR_EXCEPTION;
		strncpy((char*)fbregister.information, ex.what(), 81);
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		fbregister.flag = INFO_ERROR_EXCEPTION;
		strncpy((char*)fbregister.information, "ERROR : oracle error !", 81);
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}

bool NMOcciDB::OnModifyInfo(Peer& peer, packModifyInfo& modifyinfo, packFBModifyInfo& fbmodifyinfo)
{
 	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			// 构造sql.
			sql = "SELECT t.PASSWORD, t.NICKNAME, t.GENDER, t.BIRTHDAY, "
				"t.NATIVEPLACE, t.LOCALITY, t.VOCATION, t.COMPANY, t.REMARK"
				" FROM DBF_USER_INFO t WHERE USERID = \'" + 
				boost::lexical_cast<string>(atol((const char *)modifyinfo.userid)) + "\'"
				" OR USERMAIL = \'" + boost::lexical_cast<string>(modifyinfo.userid) + "\'"
				" AND PASSWORD = \'" + boost::lexical_cast<string>(modifyinfo.oldpassword) + "\' "
				"FOR UPDATE";
			
			memset(&fbmodifyinfo, 0, sizePackFBModifyInfo);
			fbmodifyinfo.type = MSG_PACK_FBMODIFY;
			fbmodifyinfo.packsize = sizePackFBModifyInfo;
			fbmodifyinfo.flag = INFO_ERROR_UNKOWN;

			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());
			if (!stmt.IsValid())
				break;

			COcciResultSet rs(stmt);
			if (!rs.IsValid())
				break;

			if (!rs->next())
			{
				fbmodifyinfo.flag = INFO_ERROR_NOTFOUND;
				strncpy((char*)fbmodifyinfo.information, "修改失败,未找到该用户资料!", 81);
				break;	
			}

			rs.Close();

			sql = "UPDATE DBF_USER_INFO SET "
				" PASSWORD = :1, NICKNAME = :2, GENDER = :3, BIRTHDAY = :4, NATIVEPLACE = :5,"
				" LOCALITY = :6, VOCATION = :7, COMPANY = :8, REMARK = :9"
				" WHERE USERID = \'" + boost::lexical_cast<string>(atol((const char *)modifyinfo.userid)) + "\'"
				" OR USERMAIL = \'" + boost::lexical_cast<string>(modifyinfo.userid) + "\'"
				" AND PASSWORD = \'" + boost::lexical_cast<string>(modifyinfo.oldpassword) + "\'";
			
			stmt->setSQL(sql);

			int nVal;
			string strVal;
			Date dateVal(m_env);
			DATETIME dateTimeVal = {0};

			// 用户密码.
			strVal = (char*)modifyinfo.newpassword;
			stmt->setString(1, strVal);

			// 用户昵称.
			strVal = (char*)modifyinfo.nickname;
			stmt->setString(2, strVal);

			// 用户性别.
			strVal = (char*)modifyinfo.gender;
			stmt->setString(3, strVal);

			// 用户出生日期.
			strVal = (char*)modifyinfo.birthday;
			sscanf((char*)modifyinfo.birthday, "%04d-%02d-%02d", 
				&dateTimeVal.iYear, &dateTimeVal.uiMonth, &dateTimeVal.uiDay);
			dateVal.setDate(dateTimeVal.iYear, dateTimeVal.uiMonth, dateTimeVal.uiDay);
			stmt->setDate(4, dateVal);

			// 籍贯.
			strVal = (char*)modifyinfo.nativeplace;
			stmt->setString(5, strVal);

			// 所在地.
			strVal = (char*)modifyinfo.locality;
			stmt->setString(6, strVal);

			// 所在行业.
			strVal = (char*)modifyinfo.vocation;
			stmt->setString(7, strVal);

			// 公司.
			strVal = (char*)modifyinfo.company;
			stmt->setString(8, strVal);

			// 备注信息.
			strVal = (char*)modifyinfo.remark;
			stmt->setString(9, strVal);

			// 执行sql更新.
			stmt->executeUpdate();
			// 提交事务.
			conn->commit();

			// 得到新数据.
			sql = "SELECT t.USERID, t.USERMAIL, t.USERTYPE, t.NICKNAME, t.GENDER, t.BIRTHDAY, "
				"t.NATIVEPLACE, t.LOCALITY, t.VOCATION, t.COMPANY, t.REMARK"
				" FROM DBF_USER_INFO t WHERE USERID = \'" + 
				boost::lexical_cast<string>(atol((const char *)modifyinfo.userid)) + "\'"
				" OR USERMAIL = \'" + boost::lexical_cast<string>(modifyinfo.userid) + "\'"
				" AND PASSWORD = \'" + boost::lexical_cast<string>(modifyinfo.newpassword) + "\'";

			rs.New(stmt, sql.c_str());
			if (!rs.IsValid())
				break;

			if (!rs->next())
				break;			

			// 用户ID.
			strVal = rs->getString(1);
			strncpy((char *)fbmodifyinfo.userid, strVal.c_str(), strVal.length());

			// 用户email.
			strVal = rs->getString(2);
			strncpy((char *)fbmodifyinfo.usermail, strVal.c_str(), strVal.length());

			// 用户类型.
			nVal = rs->getInt(3);
			fbmodifyinfo.usertype = nVal;

			// 用户昵称.
			strVal = rs->getString(4);
			strncpy((char *)fbmodifyinfo.nickname, strVal.c_str(), strVal.length());

			// 用户性别.
			strVal = rs->getString(5);
			strncpy((char *)fbmodifyinfo.gender, strVal.c_str(), strVal.length());

			// 用户出生日期.
			dateVal = rs->getDate(6);
			if (!dateVal.isNull())
			{
				dateVal.getDate(dateTimeVal.iYear, dateTimeVal.uiMonth, dateTimeVal.uiDay, dateTimeVal.uiHour, dateTimeVal.uiMinute, dateTimeVal.uiSecond);
				strVal = boost::str(boost::format("%1$04d-%2$02d-%3$02d")%dateTimeVal.iYear%dateTimeVal.uiMonth%dateTimeVal.uiDay);
				strncpy((char *)fbmodifyinfo.birthday, strVal.c_str(), 11);
			}			

			// 用户籍贯.
			strVal = rs->getString(7);
			strncpy((char *)fbmodifyinfo.nativeplace, strVal.c_str(), strVal.length());

			// 用户所在地.
			strVal = rs->getString(8);
			strncpy((char *)fbmodifyinfo.locality, strVal.c_str(), strVal.length());

			// 用户所在行业.
			strVal = rs->getString(9);
			strncpy((char *)fbmodifyinfo.vocation, strVal.c_str(), strVal.length());

			// 用户所在公司.
			strVal = rs->getString(10);
			strncpy((char *)fbmodifyinfo.company, strVal.c_str(), strVal.length());

			// 用户备注.
			strVal = rs->getString(11);
			strncpy((char *)fbmodifyinfo.remark, strVal.c_str(), strVal.length());

			// 写入成功信息.
			fbmodifyinfo.flag = INFO_SUCCEED;
			strncpy((char*)fbmodifyinfo.information, "修改成功!", 81);
	
			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		fbmodifyinfo.flag = INFO_ERROR_EXCEPTION;
		strncpy((char*)fbmodifyinfo.information, ex.what(), 9);
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		fbmodifyinfo.flag = INFO_ERROR_EXCEPTION;
		strncpy((char*)fbmodifyinfo.information, "ERROR : oracle error !", 81);
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}

bool NMOcciDB::OnLabels(Peer& peer, packLabels& labels, vector<packFBLabels>& fblabels)
{
	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			// 查询所有标签页.
			sql = "SELECT DBID, LABELNAME FROM DBF_DATA_LABEL";		

			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());
			if (!stmt.IsValid())
				break;

			COcciResultSet rs(stmt);
			if (!rs.IsValid())
				break;

			if (!rs->next())
				break;

			int idVal;
			string strVal;
			packFBLabels fblabel;
			int countVal = 0;
	
			do 
			{
				memset(&fblabel, 0, sizePackFBLabels);
				fblabel.type = MSG_PACK_FBLABELS;
				fblabel.packsize = sizePackFBLabels;

				idVal = rs->getInt(1);
				strVal = rs->getString(2);

				fblabel.index = countVal;
				strncpy((char *)fblabel.labelname, strVal.c_str(), strVal.length());

				fblabels.push_back(fblabel);

				countVal++;
			} while (rs->next());

			// 更新成员count.
			for_each(fblabels.begin(), fblabels.end(), bind(&packFBLabels::count, _1) = countVal);
			
			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}

bool NMOcciDB::OnRecentData(Peer& peer, packRecentData& recentdata, vector<boost::shared_ptr<BufferType> >& fbrecentdatas)
{
	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			// 查询本周记录.
			sql = "SELECT DBID, INLABELID, ISSUESTIME, INFOTITLE, INFORMATION, DATATYPE, POPULARITY, DATACOMPRESS FROM DBF_DATA_INFO "
				  "WHERE (TO_CHAR(SYSDATE, 'IW'))=(TO_CHAR(ISSUESTIME, 'IW')) AND IFISSUES != 0 ORDER BY ISSUESTIME DESC";
			
			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());
			if (!stmt.IsValid())
				break;

			COcciResultSet rs(stmt);
			if (!rs.IsValid())
				break;

			if (!rs->next())
				break;

			// 声名一些变量,用于下面使用.
			string strVal;
			packFBRecentData fbrecentdata;
			boost::shared_ptr<BufferType> fbrecentdataPtr;
			Date dateVal;
			DATETIME time;
			int length = 0;
			BufferPtr bufferVal;
			
			do 
			{
				memset(&fbrecentdata, 0, sizePackFBRecentDataHead);
				fbrecentdata.type = MSG_PACK_FBRECENTDATA;

				fbrecentdata.index = rs->getInt(1);				// 得到DBID.
				fbrecentdata.inlabelid = rs->getInt(2);			// 得到INLABELID.

				dateVal = rs->getDate(3);						// 得到ISSUESTIME.
				if (!dateVal.isNull())
				{
					dateVal.getDate(time.iYear, time.uiMonth, time.uiDay, time.uiHour, time.uiMinute, time.uiSecond);
					strVal = boost::str(boost::format("%1$04d-%2$02d-%3$02d %4$02d:%5$02d:%6$02d")%time.iYear%time.uiMonth%time.uiDay%time.uiHour%time.uiMinute%time.uiSecond);
					strncpy((char *)fbrecentdata.issuestime, strVal.c_str(), 20);
				}

				strVal = rs->getString(4);						// 得到INFOTITLE.
				strncpy((char *)fbrecentdata.infotitle, strVal.c_str(), 80);
				
				// 这里使用了malloc分配内存,因为考虑到new分配大内存有可能失败,
				// 而malloc则失败可能性大大小于new,所以使用了malloc.
				// 内存回收时,智能指针使用delete回收正确内存.但这里值得注意:
				// 因为分配的内存均是无构造类型,所以new与malloc在一定意义上是等
				// 价,delete和free也同样等价.
				Blob blobVal = rs->getBlob(5);					// 得到INFORMATION.
				if (!blobVal.isNull())
				{
					length = blobVal.length();
					bufferVal = (BufferPtr)malloc(length); // new BufferType[length];
					memset(bufferVal, 0, length);
					if (!bufferVal)
						break;
					
					int bytesRead, offset = 1;
					while ((bytesRead = 
						blobVal.read(length, bufferVal, length, offset)) > 0)
					{
						// process data read
						// move offset to read next 
						offset = offset + bytesRead;
					}
				}

				fbrecentdata.datatype = rs->getInt(6);		// 得到DATATYPE.
				fbrecentdata.popularity = rs->getInt(7);	// 得到POPULARITY.
				fbrecentdata.cpflag = rs->getInt(8);		// 得到DATACOMPRESS.

				// 计算长度.
				fbrecentdata.packsize = sizePackFBRecentDataHead + length;

				// 分配空间.
				/*new BufferType[sizePackFBRecentDataHead + length]*/
				fbrecentdataPtr.reset((BufferPtr)new BufferType[fbrecentdata.packsize]);
				if (!fbrecentdataPtr)
				{
					free(bufferVal);
					break;
				}

				// 清0.
				memset(fbrecentdataPtr.get(), 0, fbrecentdata.packsize);
				// 复制内容.
				memcpy(fbrecentdataPtr.get(), &fbrecentdata, sizePackFBRecentDataHead);
				memcpy(&((packFBRecentDataPtr)fbrecentdataPtr.get())->information[0], bufferVal, length);
			
				// 加入容器.
				fbrecentdatas.push_back(fbrecentdataPtr);

				// 清除临时空间.
				free(bufferVal);

			} while (rs->next());

			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}

bool NMOcciDB::OnTimelyData(Peer& peer, boost::shared_ptr<BufferType>& timelydataptr)
{
	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			// 查询最新1条记录.
			sql = "SELECT DBID, INLABELID, ISSUESTIME, INFOTITLE, INFORMATION, DATATYPE, POPULARITY, DATACOMPRESS FROM "
				"(SELECT DBID, INLABELID, ISSUESTIME, INFOTITLE, INFORMATION, DATATYPE, POPULARITY, IFISSUES, DATACOMPRESS FROM DBF_DATA_INFO WHERE "
				"(TO_CHAR(SYSDATE, 'IW'))=(TO_CHAR(ISSUESTIME, 'IW')) AND IFISSUES = 0 ORDER BY ISSUESTIME DESC ) "
				"WHERE ROWNUM <= 1";
			
			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());
			if (!stmt.IsValid())
				break;

			COcciResultSet rs(stmt);
			if (!rs.IsValid())
				break;

			if (!rs->next())
				break;

			// 声名一些变量,用于下面使用.
			string strVal;
			packTimelyDataPtr ptimelydata;
			packTimelyData timelydata;
			Date dateVal;
			DATETIME time;
			int length = 0;
			BufferPtr bufferVal;

			memset(&timelydata, 0, sizePackTimelyDataHead);
			timelydata.type = MSG_PACK_TIMELYDATA;

			timelydata.index = rs->getInt(1);				// 得到DBID.
			timelydata.inlabelid = rs->getInt(2);			// 得到INLABELID.

			dateVal = rs->getDate(3);						// 得到ISSUESTIME.
			if (!dateVal.isNull())
			{
				dateVal.getDate(time.iYear, time.uiMonth, time.uiDay, time.uiHour, time.uiMinute, time.uiSecond);
				strVal = boost::str(boost::format("%1$04d-%2$02d-%3$02d %4$02d:%5$02d:%6$02d")%time.iYear%time.uiMonth%time.uiDay%time.uiHour%time.uiMinute%time.uiSecond);
				strncpy((char *)timelydata.issuestime, strVal.c_str(), 20);
			}

			strVal = rs->getString(4);						// 得到INFOTITLE.
			strncpy((char *)timelydata.infotitle, strVal.c_str(), 80);

			// 这里使用了malloc分配内存,因为考虑到new分配大内存有可能失败,
			// 而malloc则失败可能性大大小于new,所以使用了malloc.
			// 内存回收时,智能指针使用delete回收正确内存.但这里值得注意:
			// 因为分配的内存均是无构造类型,所以new与malloc在一定意义上是等
			// 价,delete和free也同样等价.
			Blob blobVal = rs->getBlob(5);					// 得到INFORMATION.
			if (!blobVal.isNull())
			{
				length = blobVal.length();
				bufferVal = (BufferPtr)malloc(length); // new BufferType[length];
				memset(bufferVal, 0, length);
				if (!bufferVal)
					break;

				int bytesRead, offset = 1;
				while ((bytesRead = 
					blobVal.read(length, bufferVal, length, offset)) > 0)
				{
					// process data read
					// move offset to read next 
					offset = offset + bytesRead;
				}
			}

			timelydata.datatype = rs->getInt(6);	// 得到DATATYPE.
			timelydata.popularity = rs->getInt(7);	// 得到POPULARITY.
			timelydata.cpflag = rs->getInt(8);		// 得到DATACOMPRESS.

			// 计算长度.
			timelydata.packsize = sizePackTimelyDataHead + length;

			// 分配空间.
			ptimelydata = (packTimelyDataPtr)malloc(timelydata.packsize);
			if (!ptimelydata)
			{
				free(bufferVal);
				break;
			}

			// 清0.
			memset(ptimelydata, 0, timelydata.packsize);
			// 复制内容.
			memcpy(ptimelydata, &timelydata, sizePackTimelyDataHead);
			memcpy(&ptimelydata->information[0], bufferVal, length);

			// 加入智能指针.
			timelydataptr.reset((BufferPtr)ptimelydata);

			// 清除临时空间.
			free(bufferVal);

			// 设置为非0 (1),已发布.
			std::string updatesql = "UPDATE DBF_DATA_INFO SET IFISSUES = 1 "
				"WHERE DBID = " + boost::lexical_cast<string>(timelydata.index);
			rs.New(stmt, updatesql.c_str());

			conn->commit();

			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}

bool NMOcciDB::OnTimelyData(Peer& peer, int dbid, boost::shared_ptr<BufferType>& timelydataptr)
{
	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			// 查询最新1条记录.
			sql = "SELECT DBID, INLABELID, ISSUESTIME, INFOTITLE, INFORMATION, DATATYPE, POPULARITY, DATACOMPRESS FROM DBF_DATA_INFO "
				"WHERE DBID = " + boost::lexical_cast<string>(dbid);

			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());
			if (!stmt.IsValid())
				break;

			COcciResultSet rs(stmt);
			if (!rs.IsValid())
				break;

			if (!rs->next())
				break;

			// 声名一些变量,用于下面使用.
			string strVal;
			packTimelyDataPtr ptimelydata;
			packTimelyData timelydata;
			Date dateVal;
			DATETIME time;
			int length = 0;
			BufferPtr bufferVal;

			memset(&timelydata, 0, sizePackTimelyDataHead);
			timelydata.type = MSG_PACK_FBRECENTDATA;

			timelydata.index = rs->getInt(1);				// 得到DBID.
			timelydata.inlabelid = rs->getInt(2);			// 得到INLABELID.

			dateVal = rs->getDate(3);						// 得到ISSUESTIME.
			if (!dateVal.isNull())
			{
				dateVal.getDate(time.iYear, time.uiMonth, time.uiDay, time.uiHour, time.uiMinute, time.uiSecond);
				strVal = boost::str(boost::format("%1$04d-%2$02d-%3$02d %4$02d:%5$02d:%6$02d")%time.iYear%time.uiMonth%time.uiDay%time.uiHour%time.uiMinute%time.uiSecond);
				strncpy((char *)timelydata.issuestime, strVal.c_str(), 20);
			}

			strVal = rs->getString(4);						// 得到INFOTITLE.
			strncpy((char *)timelydata.infotitle, strVal.c_str(), 80);

			// 这里使用了malloc分配内存,因为考虑到new分配大内存有可能失败,
			// 而malloc则失败可能性大大小于new,所以使用了malloc.
			// 内存回收时,智能指针使用delete回收正确内存.但这里值得注意:
			// 因为分配的内存均是无构造类型,所以new与malloc在一定意义上是等
			// 价,delete和free也同样等价.
			Blob blobVal = rs->getBlob(5);					// 得到INFORMATION.
			if (!blobVal.isNull())
			{
				length = blobVal.length();
				bufferVal = (BufferPtr)malloc(length); // new BufferType[length];
				memset(bufferVal, 0, length);
				if (!bufferVal)
					break;

				int bytesRead, offset = 1;
				while ((bytesRead = 
					blobVal.read(length, bufferVal, length, offset)) > 0)
				{
					// process data read
					// move offset to read next 
					offset = offset + bytesRead;
				}
			}

			timelydata.datatype = rs->getInt(6);	// 得到DATATYPE.
			timelydata.popularity = rs->getInt(7);	// 得到POPULARITY.
			timelydata.cpflag = rs->getInt(8);		// 得到DATACOMPRESS.

			// 计算长度.
			timelydata.packsize = sizePackTimelyDataHead + length;

			// 分配空间.
			ptimelydata = (packTimelyDataPtr)malloc(timelydata.packsize);
			if (!ptimelydata)
			{
				free(bufferVal);
				break;
			}

			// 清0.
			memset(ptimelydata, 0, timelydata.packsize);
			// 复制内容.
			memcpy(ptimelydata, &timelydata, sizePackTimelyDataHead);
			memcpy(&ptimelydata->information[0], bufferVal, length);

			// 加入智能指针.
			timelydataptr.reset((BufferPtr)ptimelydata);

			// 清除临时空间.
			free(bufferVal);

			// 设置为非0 (1),已发布.
			std::string updatesql = "UPDATE DBF_DATA_INFO SET IFISSUES = 1 "
			"WHERE DBID = " + boost::lexical_cast<string>(dbid);
			rs.New(stmt, updatesql.c_str());

			conn->commit();

			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}

bool NMOcciDB::OnPutData(Peer& peer, const packPutDataPtr& putdataptr)
{
	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			sql = "INSERT INTO DBF_DATA_INFO ("
				"INLABELID, INFOTITLE, INFORMATION, DATATYPE, RESVERATION1, DATACOMPRESS) "
				"VALUES (:1, :2, empty_blob(), :3, :4, :5)";

			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());
			if (!stmt.IsValid())
				break;

			string strVal;

			// 所属页.
			stmt->setInt(1, putdataptr->inlabelid);

			// 标题.
			strVal = (char*)putdataptr->infotitle;
			stmt->setString(2, strVal);

			// 信息数据.
			stmt->setInt(3, putdataptr->datatype);

			// 标记下.
			int nr = rand() * rand();
			strVal = boost::lexical_cast<string> (nr);

			stmt->setString(4, strVal);
			stmt->setInt(5, putdataptr->cpflag);

			// 插入记录.
			stmt->executeUpdate();
			conn->commit(); 

			// 更新数据.
			sql = "SELECT INFORMATION, RESVERATION1 FROM DBF_DATA_INFO WHERE RESVERATION1 = ";
			sql = sql + "\'" + strVal + "\'";
			sql = sql + " FOR UPDATE";

			COcciResultSet rs(stmt, sql.c_str()); // 内部实现了execute

			if (!rs.IsValid())
				break;

			if (!rs->next())
				break;

			Blob blob = rs->getBlob(1);

			if (blob.isNull())
			{
				std::string updatesql = "UPDATE DBF_DATA_INFO SET INFORMATION = empty_blob(), RESVERATION1 = \'\' WHERE RESVERATION1 = ";
				updatesql = updatesql + "\'" + strVal + "\'";

				rs.New(stmt, updatesql.c_str());
				conn->commit();

				rs.New(stmt, sql.c_str());

				if (!rs.IsValid())
					break;

				if (!rs->next())
					break;
				// 重新得到blob字段.
				blob = rs->getBlob(1);
			}

			// 写入blob字段.
			unsigned int amt = 0;
			unsigned int buffsize = 0;
			unsigned int offset = 1;
			unsigned int writed;
			unsigned int sum = (unsigned int)putdataptr->packsize - sizePackPutDataHead;

			while (offset <= sum)
			{
				amt = buffsize = sum - offset + 1;
				writed = blob.write(amt, (unsigned char*)((&putdataptr->information) + (offset - 1)), buffsize, offset);
				offset += writed;
			}
			// 提交数据.
			conn->commit();

			// 置空RESVERATION1.
			std::string updatesql = "UPDATE DBF_DATA_INFO SET RESVERATION1 = \'\' WHERE RESVERATION1 = ";
			updatesql = updatesql + "\'" + strVal + "\'";
			rs.New(stmt, updatesql.c_str());

			conn->commit();

			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}

bool NMOcciDB::OnTest(string& str)
{
	bool bRet = false;
	COcciConn conn;
	string sql;

	try
	{
		do 
		{
			/************************************************************************
			假设有存储过程:														
			create or replace procedure jl_test
			(a in varchar2,b out varchar2)
			as
			begin
			b:= a;
			end;
			执行则相当于赋值.
			************************************************************************/
			sql = "BEGIN jl_test(:1, :2); END;";

			conn.New(m_scp);
			if (!conn.IsValid())
				break;

			COcciStatement stmt(conn, sql.c_str());
			if (!stmt.IsValid())
				break;

			str = "hello";

			stmt->setString(1, string("str"));
			stmt->setString(2, str);

			stmt->registerOutParam(2, OCCISTRING, 30, "");

			stmt->executeUpdate();

			str = stmt->getString(1);

			bRet = true;
		} while (0);
	}
	catch (SQLException &ex)
	{
		TRACE1("ERROR : %s\n", ex.what());
	}
	catch (...)
	{
		TRACE0("ERROR : oracle error !\n");
	}

	return bRet;
}